static int __init boot_of_cpus(void)
{
- int cpus;
- int cpu, bootcpu, logical;
+ int cpus_node;
+ int cpu_node, bootcpu_node, logical;
int result;
+ s32 cpuid;
u32 cpu_clock[2];
+ extern uint cpu_hard_id[NR_CPUS];
- cpus = of_finddevice("/cpus");
- cpu = of_getchild(cpus);
- result = of_getprop(cpu, "timebase-frequency", &timebase_freq,
+ /* Look up which CPU we are running on right now and get all info
+ * from there */
+ result = of_getprop(bof_chosen, "cpu",
+ &bootcpu_node, sizeof (bootcpu_node));
+ if (result == OF_FAILURE)
+ of_panic("Failed to look up boot cpu\n");
+
+ cpu_node = bootcpu_node;
+
+ result = of_getprop(cpu_node, "timebase-frequency", &timebase_freq,
sizeof(timebase_freq));
if (result == OF_FAILURE) {
of_panic("Couldn't get timebase frequency!\n");
}
of_printf("OF: timebase-frequency = %d Hz\n", timebase_freq);
- result = of_getprop(cpu, "clock-frequency", &cpu_clock, sizeof(cpu_clock));
+ result = of_getprop(cpu_node, "clock-frequency",
+ &cpu_clock, sizeof(cpu_clock));
if (result == OF_FAILURE || (result !=4 && result != 8)) {
of_panic("Couldn't get clock frequency!\n");
}
cpu_khz /= 1000;
of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz);
- /* Look up which CPU we are running on right now. */
- result = of_getprop(bof_chosen, "cpu", &bootcpu, sizeof (bootcpu));
- if (result == OF_FAILURE)
- of_panic("Failed to look up boot cpu\n");
-
- cpu = of_getpeer(cpu);
-
- /* We want a continuous logical cpu number space. */
+ /* We want a continuous logical cpu number space and we'll make
+ * the booting CPU logical 0. */
cpu_set(0, cpu_present_map);
cpu_set(0, cpu_online_map);
cpu_set(0, cpu_possible_map);
- /* Spin up all CPUS, even if there are more than NR_CPUS, because
- * Open Firmware has them spinning on cache lines which will
- * eventually be scrubbed, which could lead to random CPU activation.
- */
- for (logical = 1; cpu > 0; logical++) {
- unsigned int cpuid, ping, pong;
- unsigned long now, then, timeout;
-
- if (cpu == bootcpu) {
- of_printf("skipping boot cpu!\n");
- continue;
- }
+ result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+ cpu_hard_id[0] = cpuid;
- result = of_getprop(cpu, "reg", &cpuid, sizeof(cpuid));
- if (result == OF_FAILURE)
- of_panic("cpuid lookup failed\n");
+ /* Spin up all CPUS, even if there are more than NR_CPUS or we are
+ * runnign nosmp, because Open Firmware has them spinning on cache
+ * lines which will eventually be scrubbed, which could lead to
+ * random CPU activation.
+ */
- of_printf("spinning up secondary processor #%d: ", logical);
+ /* Find the base of the multi-CPU package node */
+ cpus_node = of_finddevice("/cpus");
+ if (cpus_node <= 0) {
+ of_printf("Single Processor System\n");
+ return 1;
+ }
+ /* Start with the first child */
+ cpu_node = of_getchild(cpus_node);
- __spin_ack = ~0x0;
- ping = __spin_ack;
- pong = __spin_ack;
- of_printf("ping = 0x%x: ", ping);
+ for (logical = 1; cpu_node > 0; logical++) {
+ unsigned int ping, pong;
+ unsigned long now, then, timeout;
+
+ if (cpu_node == bootcpu_node) {
+ /* same CPU as boot CPU shich we have already made 0 so
+ * reduce the logical count */
+ --logical;
+ } else {
+ result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+ if (result == OF_FAILURE)
+ of_panic("cpuid lookup failed\n");
- mb();
- result = of_start_cpu(cpu, (ulong)spin_start, logical);
- if (result == OF_FAILURE)
- of_panic("start cpu failed\n");
+ cpu_hard_id[logical] = cpuid;
- /* We will give the secondary processor five seconds to reply. */
- then = mftb();
- timeout = then + (5 * timebase_freq);
+ of_printf("spinning up secondary processor #%d: ", logical);
- do {
- now = mftb();
- if (now >= timeout) {
- of_printf("BROKEN: ");
- break;
- }
+ __spin_ack = ~0x0;
+ ping = __spin_ack;
+ pong = __spin_ack;
+ of_printf("ping = 0x%x: ", ping);
mb();
- pong = __spin_ack;
- } while (pong == ping);
- of_printf("pong = 0x%x\n", pong);
+ result = of_start_cpu(cpu_node, (ulong)spin_start, logical);
+ if (result == OF_FAILURE)
+ of_panic("start cpu failed\n");
+
+ /* We will give the secondary processor five seconds to reply. */
+ then = mftb();
+ timeout = then + (5 * timebase_freq);
+
+ do {
+ now = mftb();
+ if (now >= timeout) {
+ of_printf("BROKEN: ");
+ break;
+ }
- if (pong != ping) {
- cpu_set(logical, cpu_present_map);
- cpu_set(logical, cpu_possible_map);
- }
+ mb();
+ pong = __spin_ack;
+ } while (pong == ping);
+ of_printf("pong = 0x%x\n", pong);
- cpu = of_getpeer(cpu);
+ if (pong != ping) {
+ cpu_set(logical, cpu_present_map);
+ cpu_set(logical, cpu_possible_map);
+ }
+ }
+ cpu_node = of_getpeer(cpu_node);
}
return 1;
}